package com.lc.datagram;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.util.Iterator;

import org.junit.Test;

/**
 * @author 逝兮诚
 * @date 2017年6月21日 上午11:02:02
 * @see DatagramChannel是对于UDP协议的，管发不管收，这里有服务端的发送和接收，客户端的发送和接收
 */
public class DatagramChannelTest {

	/**
	 * 发包的datagram
	 * 
	 * @throws IOException
	 * @throws InterruptedException
	 */
	@Test
	public void sendDatagram() throws IOException, InterruptedException {
		DatagramChannel sendChannel = DatagramChannel.open();
		InetSocketAddress sendAddress = new InetSocketAddress("127.0.0.1", 9999);
		while (true) {
			sendChannel.send(ByteBuffer.wrap("发包".getBytes("UTF-8")), sendAddress);
			System.out.println("发包端发包");
			Thread.sleep(1000);
		}
	}

	/**
	 * 收包端
	 * 
	 * @throws IOException
	 */
	@Test
	public void receive() throws IOException {
		DatagramChannel receiveChannel = DatagramChannel.open();
		InetSocketAddress receiveAddress = new InetSocketAddress(9999);
		receiveChannel.bind(receiveAddress);
		ByteBuffer receiveBuffer = ByteBuffer.allocate(512);
		while (true) {
			receiveBuffer.clear();
			SocketAddress sendAddress = receiveChannel.receive(receiveBuffer);
			receiveBuffer.flip();
			System.out.print(sendAddress.toString() + " ");
			System.out.println(Charset.forName("UTF-8").decode(receiveBuffer));
		}
	}

	/**
	 * 只接收和发送9999的数据包
	 * 
	 * @throws IOException
	 */
	@Test
	public void testConect1() throws IOException {
		DatagramChannel connChannel = DatagramChannel.open();
		connChannel.bind(new InetSocketAddress(9998));
		connChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
		connChannel.write(ByteBuffer.wrap("发包".getBytes("UTF-8")));
		ByteBuffer readBuffer = ByteBuffer.allocate(512);
		while (true) {
			try {
				readBuffer.clear();
				connChannel.read(readBuffer);
				readBuffer.flip();
				System.out.println(Charset.forName("UTF-8").decode(readBuffer));
			} catch (Exception e) {

			}
		}
	}

	/**
	 * 只接收和发送9998的数据包
	 * 
	 * @throws IOException
	 */
	@Test
	public void testConect2() throws IOException {
		DatagramChannel connChannel = DatagramChannel.open();
		connChannel.bind(new InetSocketAddress(9999));
		connChannel.connect(new InetSocketAddress("127.0.0.1", 9998));
		while (true) {
			connChannel.write(ByteBuffer.wrap("发包".getBytes("UTF-8")));
			System.out.println("发包成功");
		}
	}

	/**
	 * 服务端接收和发送
	 */
	@Test
	public void udpServerSendTest() {
		Selector selector = null;
		DatagramChannel server;
		try {
			selector = Selector.open();
			server = DatagramChannel.open();
			server.configureBlocking(false);
			server.socket().bind(new InetSocketAddress(10086));
			server.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
			while (true) {
				int n = selector.select();
				if (n == 0)
					continue;
				Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
				while (keys.hasNext()) {
					SelectionKey selKey = (SelectionKey) keys.next();
					if (selKey.isReadable()) {
						DatagramChannel sendChannel = (DatagramChannel)selKey.channel();
						ByteBuffer receiveBuffer = ByteBuffer.allocate(64);
						receiveBuffer.clear();
						SocketAddress receiveAddr = sendChannel.receive(receiveBuffer);
						receiveBuffer.flip();
						System.out.println(Charset.forName("UTF-8").decode(receiveBuffer));
						
						ByteBuffer sendBuffer = ByteBuffer.allocate(64);
						sendBuffer.clear();
						sendBuffer.put("service send".getBytes("UTF-8"));
						sendBuffer.flip();
						server.send(sendBuffer, receiveAddr);
					} else if (selKey.isWritable()) {

					}
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 服务端发送和接收
	 * 
	 * @throws InterruptedException
	 */
	@Test
	public void udpWriteConnTest() throws InterruptedException {
		DatagramChannel client;
		try {
			client = DatagramChannel.open();
			client.configureBlocking(false);
			client.connect(new InetSocketAddress("127.0.0.1", 10086));
			System.out.println(client.getLocalAddress());
			client.write(ByteBuffer.wrap("success".getBytes()));
			while (true) {
				ByteBuffer sendBuffer = ByteBuffer.allocate(100);
				int readSize = client.read(sendBuffer);
				if (readSize == 0)
					continue;
				System.out.println(readSize);
				sendBuffer.flip();
				while (sendBuffer.hasRemaining()) {
					System.out.print((char) sendBuffer.get());
				}
				sendBuffer.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
